
//
// 110222 - AH - Created.
//

package org.soekrat.gui.swing.studio;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JPopupMenu;
import javax.swing.JTree;

/**
 * <p>
 *   Popup
 *   {@link JPopupMenu} or base class for objects that handles popup events.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC)  
 */
public final class PopupListener
{
  private JPopupMenu m_popup=null;  
  
  private final Component m_component;

  // Catch mouse events and react on popup trigger.
  private final MouseAdapter m_ml=new MouseAdapter()
  {
    public void mousePressed(MouseEvent e){ checkPopup(e); }
    public void mouseClicked(MouseEvent e){ checkPopup(e); }
    public void mouseReleased(MouseEvent e){ checkPopup(e); }
    private void checkPopup(MouseEvent e)
    {
      if (e.isPopupTrigger()) doPopup(e);
    }
  };
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * <p>
   *   Will select in view (works only for 
   *   {@link JTree}): Equal to
   *   {@link #PopupListener(JPopupMenu, Component, boolean) new PopupListener(popup, component, true)}. 
   * </p>
   * @param popup     {@link JPopupMenu} to popup.
   * @param component {@link Component} that publishes
   *                  {@link MouseEvent}s.
   */
  public PopupListener(JPopupMenu popup, Component component)
  {
  	this(popup, component, true);
  }

  /**
   * <p>
   *   Constructor.
   * </p>
   * @param popup     {@link JPopupMenu} to popup.
   * @param component {@link Component} that publishes
   *                  {@link MouseEvent}s.
   * @param select    True if triggered popup event also should select in view at the
   *                  event's position (currently only work for
   *                  {@link JTree}}, false if is not to.
   */
  public PopupListener(JPopupMenu popup, Component component, boolean select)
  {
    if (popup==null)
    {
      throw new NullPointerException("popup");
    }
    if (component==null)
    {
      throw new NullPointerException("component");
    }
    
    m_component=component;    
    
    m_popup=popup;
    m_component.addMouseListener(m_ml);    
  }
  
  /**
   * <p>
   *   Register popup meny or unregister popup menu.
   * </p>
   * @param v False if to disable menu, true if to enable.
   */
  public void setEnabled(boolean v)
  {
    if (v) m_component.addMouseListener(m_ml);
    else   m_component.removeMouseListener(m_ml);
  }

  /**
   * <p>
   *   Derived classes may overide this in order to respond to popup events.
   * </p>
   * @param e Event.
   */
  protected void doPopup(MouseEvent e)
  {
    int x=e.getX();
    int y=e.getY();          
    m_popup.show((Component)e.getSource(), x, y);    
  }

}
